package com.guchenbo.study.xml;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 演示bean的生命周期
 * Spring揭秘一文中写道的周期：实例化bean对象 --> 设置对象属性 --> 检测Aware接口
 * --> BeanPostProcessor前置逻辑 --> InitializingBean逻辑 --> init-method逻辑
 * --> BeanPostProcessor后置逻辑 --> 使用中 --> DisposableBean逻辑 --> destroy-method逻辑
 *
 * @Author guchenbo
 * @Date 2019/4/7.
 */
public class BeanLifeCycleTest implements ApplicationContextAware, InitializingBean, DisposableBean {
    private String name;

    public BeanLifeCycleTest() {
        sout("实例化bean对象");
    }

    public void setName(String name) {
        this.name = name;
        sout("设置对象属性");
    }

    public void doing() {
        sout("使用中");
    }

    public void initMethod() {
        sout("init-method逻辑");
    }

    public void destroyMethod() {
        sout("destroy-method逻辑");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        sout("检测Aware接口");
    }

    @Override
    public void destroy() throws Exception {
        sout("DisposableBean逻辑");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        sout("InitializingBean逻辑");
    }

    public static class BeanFactoryProcessorTest implements BeanPostProcessor {

        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            sout("BeanPostProcessor前置逻辑");
            return bean;
        }

        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            sout("BeanPostProcessor后置逻辑");
            return bean;
        }

    }

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("lifecycle.xml");
        BeanLifeCycleTest lifeCycleTest = (BeanLifeCycleTest) context.getBean("lifeCycleTest");
        lifeCycleTest.doing();
        context.destroy();
    }

    public static void sout(String str) {
        System.out.println(BeanLifeCycleTest.class.getSimpleName() + " : " + str);
    }
}
